﻿using Microsoft.Extensions.DependencyInjection;
using StarsAdmin.Core.App;
using StarsAdmin.Core.Helpers;
using System.Collections;

namespace StarsAdmin.Core.DB.SeedData
{
    public static class InitSeedData
    {
        public static void InitializeData()
        {
            using var scope = AppHelper.ServiceProvider.CreateScope();

            var context = AppHelper.GetService<DBContext>();

            if (context.Menus == null || context.Roles == null || context.Users == null)
            {
                // 确保数据库存在，如果数据库不存在则创建数据库，存在则什么也不做
                context.Database.EnsureCreated();
            }

            // 如果已经有数据，则跳过
            if (context.Menus.Any() || context.Roles.Any() || context.Users.Any())
            {
                return;
            }

            Console.WriteLine(" ----------------------------- 数据库初始化开始 ----------------------------- ");

            var result = ExecuteSeedData(context);

            if (result)
            {
                Console.WriteLine(" ----------------------------- 数据库初始化成功 ----------------------------- ");
            } else
            {
                Console.WriteLine(" ----------------------------- 数据库初始化失败 ----------------------------- ");
            }
        }

        private static bool ExecuteSeedData(DBContext context)
        {
            // 获取指定程序集下实现了 IEntitySeedData 接口的类
            var seedDataTypes = AssemblyHelper.GetAssemblyByName("StarsAdmin.Core").GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEntitySeedData<>)));

            foreach (var seedDataType in seedDataTypes)
            {
                // 获取泛型参数
                var entityType = seedDataType.GetInterfaces().First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEntitySeedData<>)).GetGenericArguments()[0];

                // 创建实例
                var seedDataInstance = Activator.CreateInstance(seedDataType);

                // 调用 HasData 方法
                var hasDataMethod = seedDataType.GetMethod("HasData");
                var data = hasDataMethod?.Invoke(seedDataInstance, null) as IEnumerable;

                if (data != null)
                {
                    // 动态获取 Set<TEntity> 方法并调用
                    var setMethod = typeof(DBContext).GetMethod("Set", Type.EmptyTypes)?.MakeGenericMethod(entityType);
                    var dbSet = setMethod?.Invoke(context, null);

                    // 添加数据到上下文中
                    foreach (var item in data)
                    {
                        // 直接调用 Add 方法，不再使用 MakeGenericMethod
                        dbSet?.GetType().GetMethod("Add")?.Invoke(dbSet, [item]);
                    }
                }
            }
            return context.SaveChanges() > 0;
        }
    }
}